2020-2021 Sunseeker Telemetry and Lighting System
timer_d_ex8_dutyCycleMeasurementSingle.c
Go to the documentation of this file.
1 /* --COPYRIGHT--,BSD
2  * Copyright (c) 2017, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  * --/COPYRIGHT--*/
32 //******************************************************************************
33 // MSP430F51x2 Demo - TimerD0, Single Input Capture mode, Normal Timer Mode
34 // Input Period and Dutycycle measurement
35 // Description: This code example implements input capture in single capture
36 // mode using TimerD in normal timer mode. TD1.1 is configured to output PWM
37 // of 25% dutycycle, that is used as capture input at TD0.1. TD0.1 is
38 // configured as timer input capture that is triggered by both the rising and
39 // the falling edges. An external connection between TD1.1 and TD0.1 is
40 // required. Rising and Falling edges are captured and the dutycycle is
41 // computed. If the measured dutycycle is != 25%, then LED on P1.0 is set.
42 //
43 // ACLK = LFXT1 = 32kHz; SMCLK = MCLK = 2.45MHz;
44 //
45 // MSP430F51x2
46 // -----------------
47 // /|\| XIN|-
48 // | | | 32kHz
49 // --|RST XOUT|-
50 // | |
51 // | P1.7/TD0.1|<-- CCI1A <-|
52 // | P2.2/TD1.1|--> CCR1 -->|
53 // | |
54 // | P1.0|--> LED "ON" when dutycycle != 25%
55 // | |
56 //
57 //******************************************************************************
58 #include "driverlib.h"
59 
60 uint8_t Count, First_Time;
61 uint16_t REdge1, REdge2, FEdge;
62 uint16_t Period, ON_Period;
63 uint8_t DutyCycle;
64 void main(void)
65 {
66  // Stop watchdog timer
67  WDT_A_hold(WDT_A_BASE);
68 
69  GPIO_setAsOutputPin(
70  GPIO_PORT_P1,
71  GPIO_PIN0
72  );
73  // LED off
75  GPIO_PORT_P1,
76  GPIO_PIN0
77  );
78 
79  // Configure XT1
80  // Port select XT1
81  GPIO_setAsPeripheralModuleFunctionInputPin(
82  GPIO_PORT_PJ,
83  GPIO_PIN4 + GPIO_PIN5
84  );
85  UCS_turnOnLFXT1 (UCS_XT1_DRIVE_3,
86  UCS_XCAP_3
87  );
88 
89  // Initialize DCO to 2.45MHz
90  UCS_initFLLSettle(2450,
91  74);
92 
93  // Loop until XT1 & DCO fault flag is cleared
94  // Configure Port Pins
95  // P2.2/TD1.1 Output TD1.1 Option select
96  GPIO_setAsPeripheralModuleFunctionOutputPin(
97  GPIO_PORT_P2,
98  GPIO_PIN2
99  );
100  // P1.7/TD0.1 Input Capture TD0.1 option select
101  GPIO_setAsPeripheralModuleFunctionInputPin(
102  GPIO_PORT_P1,
103  GPIO_PIN7
104  );
105 
106  // Configure TD1.1 to output PWM signal
107  // Period = 82/32khz = 2.5ms ~ 400Hz Freq
108  Timer_D_initCompareModeParam initCompParam = {0};
109  initCompParam.compareRegister = TIMER_D_CAPTURECOMPARE_REGISTER_1;
110  initCompParam.compareInterruptEnable = TIMER_D_CAPTURECOMPARE_INTERRUPT_DISABLE;
111  initCompParam.compareOutputMode = TIMER_D_OUTPUTMODE_RESET_SET;
112  initCompParam.compareValue = 21;
113  Timer_D_initCompareMode(TIMER_D0_BASE, &initCompParam);
114 
115  Timer_D_initUpModeParam initUpParam = {0};
116  initUpParam.clockSource = TIMER_D_CLOCKSOURCE_ACLK;
117  initUpParam.clockSourceDivider = TIMER_D_CLOCKSOURCE_DIVIDER_1;
118  initUpParam.clockingMode = TIMER_D_CLOCKINGMODE_EXTERNAL_CLOCK;
119  initUpParam.timerPeriod = 82-1;
120  initUpParam.timerInterruptEnable_TDIE = TIMER_D_TDIE_INTERRUPT_DISABLE;
121  initUpParam.captureCompareInterruptEnable_CCR0_CCIE =
122  TIMER_D_CAPTURECOMPARE_INTERRUPT_DISABLE;
123  initUpParam.timerClear = TIMER_D_DO_CLEAR;
124  Timer_D_initUpMode(TIMER_D1_BASE, &initUpParam);
125 
126  Timer_D_initContinuousModeParam initContParam = {0};
127  initContParam.clockSource = TIMER_D_CLOCKSOURCE_SMCLK;
128  initContParam.clockSourceDivider = TIMER_D_CLOCKSOURCE_DIVIDER_1;
129  initContParam.clockingMode = TIMER_D_CLOCKINGMODE_EXTERNAL_CLOCK;
130  initContParam.timerInterruptEnable_TDIE = TIMER_D_TDIE_INTERRUPT_DISABLE;
131  initContParam.timerClear = TIMER_D_DO_CLEAR;
132  Timer_D_initContinuousMode(TIMER_D0_BASE, &initContParam);
133 
134  Timer_D_startCounter(TIMER_D0_BASE,
135  TIMER_D_CONTINUOUS_MODE
136  );
137 
138  Timer_D_startCounter(TIMER_D1_BASE,
139  TIMER_D_UP_MODE
140  );
141 
142  Timer_D_clearCaptureCompareInterrupt(TIMER_D0_BASE,
143  TIMER_D_CAPTURECOMPARE_REGISTER_1);
144 
145  Timer_D_initCaptureModeParam initCapParam = {0};
146  initCapParam.captureRegister = TIMER_D_CAPTURECOMPARE_REGISTER_1;
147  initCapParam.captureMode = TIMER_D_CAPTUREMODE_RISING_AND_FALLING_EDGE;
148  initCapParam.captureInputSelect = TIMER_D_CAPTURE_INPUTSELECT_CCIxA;
149  initCapParam.synchronizeCaptureSource = TIMER_D_CAPTURE_SYNCHRONOUS;
150  initCapParam.captureInterruptEnable = TIMER_D_CAPTURECOMPARE_INTERRUPT_ENABLE;
151  initCapParam.captureOutputMode = TIMER_D_OUTPUTMODE_OUTBITVALUE;
152  initCapParam.channelCaptureMode = TIMER_D_SINGLE_CAPTURE_MODE;
153  Timer_D_initCaptureMode(TIMER_D0_BASE, &initCapParam);
154 
155  // Variable Initialization
156  Count = 0x0;
157  First_Time = 0x01;
158 
159  while(1)
160  {
161  __bis_SR_register(LPM0_bits + GIE); // Enter LPM0
162  __no_operation(); // For debugger
163  // On exiting LPM0
164  if (TIMER_D_CAPTURE_OVERFLOW == Timer_D_getCaptureCompareInterruptStatus
165  (TIMER_D0_BASE,
166  TIMER_D_CAPTURECOMPARE_REGISTER_1,
167  TIMER_D_CAPTURE_OVERFLOW
168  ) ) // Check for Capture Overflow
169  while(1); // Loop Forever
170 
171  Period = REdge2 - REdge1; // Calculate Period
172  ON_Period = FEdge-REdge1; // On period
173  DutyCycle = ((uint32_t)ON_Period*100/Period);
174  if(DutyCycle!= 25)
175  {
177  GPIO_PORT_P1,
178  GPIO_PIN0
179  );
180  }
181  }
182 }
183 
184 // TD0_D1 Interrupt vector
185 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
186 #pragma vector=TIMER0_D1_VECTOR
187 __interrupt
188 #elif defined(__GNUC__)
189 __attribute__((interrupt(TIMER0_D1_VECTOR)))
190 #endif
191 void TIMER0_D1_ISR (void)
192 {
193  switch(__even_in_range(TD0IV,0x1E))
194  {
195  case 0x0: break; // Vector 0: No interrupt
196  case 0x2: // Vector 2: TDCCR1 CCIFG
197  // Capture Input Pin Status
198  if(TIMER_D_CAPTURECOMPARE_INPUT == Timer_D_getCaptureCompareInputSignal(TIMER_D0_BASE,
199  TIMER_D_CAPTURECOMPARE_REGISTER_1))
200  {
201  // Rising Edge was captured
202  if (!Count)
203  {
204  REdge1 = Timer_D_getCaptureCompareCount(TIMER_D0_BASE,
205  TIMER_D_CAPTURECOMPARE_REGISTER_1);
206  Count++;
207  }
208  else
209  {
210  REdge2 = Timer_D_getCaptureCompareCount(TIMER_D0_BASE,
211  TIMER_D_CAPTURECOMPARE_REGISTER_1);
212  Count=0x0;
213  __bic_SR_register_on_exit(LPM0_bits + GIE); // Exit LPM0 on return to main
214  }
215 
216  if (First_Time)
217  First_Time = 0x0;
218  }
219 
220  else
221  {
222  // Falling Edge was captured
223  if(!First_Time)
224  {
225  FEdge = Timer_D_getCaptureCompareCount(TIMER_D0_BASE,
226  TIMER_D_CAPTURECOMPARE_REGISTER_1);
227  }
228  }
229  break;
230  case 0x4: break; // Vector 4: TDCCR2 CCIFG
231  case 0x6: break; // Vector 6: TDCCR3 CCIFG
232  case 0x8: break; // Vector 8: TDCCR4 CCIFG
233  case 0xA: break; // Vector 10: TDCCR5 CCIFG
234  case 0xC: break; // Vector 12: TDCCR5 CCIFG
235  case 0xE: break; // Vector 14: -
236  case 0x10:break; // Vector 16: TDIFG
237  case 0x12:break; // Vector 18: TDHINT TDHFLIFG
238  case 0x14:break; // Vector 20: TDHINT TDHFHIFG
239  case 0x16:break; // Vector 22: TDHINT TDHLKIFG
240  case 0x18:break; // Vector 24: TDHINT TDHUNLKIFG
241  case 0x1A:break; // Vector 26: -
242  case 0x1C:break; // Vector 28: -
243  case 0x1E:break; // Vector 28: -
244  default: break;
245  }
246 }
__no_operation()
__bic_SR_register_on_exit(LPM3_bits|GIE)
GPIO_setOutputHighOnPin(GPIO_PORT_LED1|GPIO_PORT_LED2, GPIO_PIN_LED1|GPIO_PIN_LED2)
GPIO_setOutputLowOnPin(GPIO_PORT_LED1|GPIO_PORT_LED2, GPIO_PIN_LED1|GPIO_PIN_LED2)